-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Fix Annotations time formats
#13109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Annotations time formats
#13109
Conversation
…s/mne-python into fix_annotations_orig_time
|
Also updated the docstring for |
|
The code for annotations works fine, but changing This is an alternative approach to fix the current errors: but I'm not 100% on how others want to proceed so I'll pause for now. |
|
Hey @drammock, please could I get your input on the proposed changes. The original annotations issue is resolved, but there are some implementation details that weren't discussed in the issue that I'd like to get suggestions on. |
Turns out this doesn't fully resolve things. Once the proposed changes to |
larsoner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tsbinns do you still need feedback on the correct change here? One way forward would be to pick whichever you think would be best, get tests green, and we can see what the impact is...
|
@larsoner I'll have a look through this again tomorrow and refamiliarise myself/start trying to fix the failures. Then will see if I have some more concrete questions then! |
|
Okay, so everything is green now. This PR changes it so that nanoseconds in times will be dropped on reading annotations. As noted here (#13108 (comment)), sanitising on read will prevent issues with annotations created with MNE v1.7-1.10, as well as any created moving forward, so I think this could be considered a sufficient solution already. Still, that comment also mentions sanitising annotations on write by adapting For example, if I create annotations on MNE 1.11 (when it's released), I might want to share these annotations with colleagues who are using different environments and different MNE versions. If they are using MNE < 1.11, they will encounter the same issues reading these annotations, which would be avoided if we sanitise annotations on write. Rather than altering def to_data_frame(self, time_format="datetime"):
"""Export annotations in tabular structure as a pandas DataFrame.
...
"""
pd = _check_pandas_installed(strict=True)
valid_time_formats = ["ms", "timedelta", "datetime"]
dt = _handle_meas_date(self.orig_time)
if dt is None:
dt = _handle_meas_date(0)
time_format = _check_time_format(time_format, valid_time_formats, dt)
dt = dt.replace(tzinfo=None)
times = _convert_times(self.onset, time_format, dt)
# ↓↓↓ New code
if time_format == "datetime":
# remove nanoseconds
tz_name = (
f", {meas_date.tzinfo.tzname(meas_date)}" if meas_date is not None else ""
)
times = times.astype(f"datetime64[us{tz_name}]")
# -------------------
df = dict(onset=times, duration=self.duration, description=self.description)
if self._any_ch_names():
df.update(ch_names=self.ch_names)
df = pd.DataFrame(df)
extras_df = pd.DataFrame(self.extras)
df = pd.concat([df, extras_df], axis=1)
return dfAlternatively, if people feel datetimes for all dataframes should not contain nanoseconds, I am happy to discuss this, but I feel those changes go beyond the scope of this PR. |
Have you considered and then only in the places you need it for annots you call with |
|
Yeah, I can do that. |
|
Yeah I think so. Though admittedly I do not have my head 100% wrapped around the issue, so happy to go with what you think makes sense @tsbinns , I think you have given this issue (much) more deliberate consideration! |
|
Okay. I haven't seen any issues reported with nanoseconds in dataframe conversions of other classes, so I'll keep it simple and stick with enabling this only for annotations! |
|
Just pushed a commit that drops nanoseconds only for |
larsoner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of tiny comments, @drammock did you want to look as well?
|
That's @larsoner's comments addressed. Here's an example of what the warning about bad |
Reference issue (if any)
Fixes #13108
What does this implement/fix?
When reading annotations from a csv file, truncates nanoseconds from
orig_timeby converting to the microsecond format. The exception is for the default time of1970-01-01 00:00:00used in the files whenAnnotations.orig_time=None, as converting this to microseconds would cause it to be read as a proper time rather than being converted toNonewhich is intended.Also truncates nanoseconds from the times in
utils.dataframes._convert_times()whentime_format="datetime"by converting todtype=datetime64[us].Should this also be done when
time_format="timedelta"?Finally, updates unit tests that check csv files with nanosecond times get assigned proper
orig_timewhen read in and checks thatAnnotations.to_data_frame()returns times with nanoseconds truncated (which in turn means truncated times are saved).